//
// Created by HZH on 2023-05-01.
//

#include <string.h>
#include <stdio.h>
#include "BzDB_BzArray_t.h"

/**
 *
 * @param bzArray
 * @param buf
 * @param buffer_size  buffer中每一个元素的sizeof
 * @param buffer_len    buffer中总共有多少个元素
 */
void BzDB_BzArray_init(BzDB_BzArray_t *bzArray , void * buf, int buffer_size  , int buffer_len){
    bzArray->buf = buf;
    bzArray->buffer_size = buffer_size;
    bzArray->max_len = buffer_len;
    bzArray->used_count = 0;
}

/**
*
 * get
 * insert
 * update
 * delete
 *
 *
 *
 *
*/

//Uint
/**
 *  判断index是否合法
 * @param bzArray
 * @param index
 * @return
 */
CCBOOL BzDB_BzArray_private_is_index_valid(BzDB_BzArray_t *bzArray,int index)
{
    if( index < 0){//index 不可以小于0
        return FALSE;
    }

    if(index > bzArray->used_count ){
        return FALSE;
    }
    if(bzArray->used_count > bzArray->max_len){
        return FALSE;
    }
    return TRUE;
}


CCBOOL BzDB_BzArray_get(BzDB_BzArray_t *bzArray , int index , void * res)
{
    CCBOOL is_index_valid = BzDB_BzArray_private_is_index_valid(bzArray,index);
    if(!is_index_valid){
        return FALSE;
    }

    // 元素的起始地址
    void* item_address = bzArray->buf + bzArray->buffer_size*index;

    memcpy(res,item_address,bzArray->buffer_size);
    return TRUE;
}
CCBOOL BzDB_BzArray_insert(BzDB_BzArray_t *bzArray , int index , void * pdata)
{
    CCBOOL is_index_valid = BzDB_BzArray_private_is_index_valid(bzArray,index);
    if(!is_index_valid){
        return FALSE;
    }


    //  index index+1 ,    ....  , use_count
    //    x       x            x

    // 元素的起始地址
    // 所有元素向后移动
    //  count <- count-1
    // ....
    // index+1 <- index
    for(int i = bzArray->used_count - 1 ; i >= index ; i--){

        void * p1 = bzArray->buf + i     * bzArray->buffer_size;
        void * p2 = bzArray->buf + (i+1) * bzArray->buffer_size;
        memcpy( p2 , p1 , bzArray->buffer_size  );
    }

    void* item_address = bzArray->buf + bzArray->buffer_size*index;
    memcpy(item_address,pdata,bzArray->buffer_size);

    bzArray->used_count = bzArray->used_count + 1;
    return TRUE;

}
CCBOOL BzDB_BzArray_delete(BzDB_BzArray_t *bzArray , int index , void * res)
{
    CCBOOL is_index_valid = BzDB_BzArray_private_is_index_valid(bzArray,index);
    if(!is_index_valid){
        return FALSE;
    }

    void* item_address = bzArray->buf + bzArray->buffer_size*index;
    memcpy(res,item_address,bzArray->buffer_size);

    // 从后往前覆盖
    // index <- index+1
    // used_count-2 <- used_count-1
    for(int i = index ; i <=bzArray->used_count-2 ; i++)
    {
        void * p1 = bzArray->buf + i     * bzArray->buffer_size;
        void * p2 = bzArray->buf + (i+1) * bzArray->buffer_size;
        memcpy( p1 , p2 , bzArray->buffer_size  );
    }
    bzArray->used_count = bzArray->used_count - 1;
    return TRUE;

}
CCBOOL BzDB_BzArray_update(BzDB_BzArray_t *bzArray , int index , void * res)
{
    CCBOOL is_index_valid = BzDB_BzArray_private_is_index_valid(bzArray,index);
    if(!is_index_valid){
        return FALSE;
    }
    // 直接更新
    void* item_address = bzArray->buf + bzArray->buffer_size*index;
    memcpy(res,item_address,bzArray->buffer_size);
    return TRUE;
}




CCBOOL BzDB_BzArray_get_last(BzDB_BzArray_t *bzArray  , void * res)
{
    int index = bzArray->used_count-1;
    return BzDB_BzArray_get(bzArray,index,res);
}

CCBOOL BzDB_BzArray_get_first(BzDB_BzArray_t *bzArray  , void * res)
{
    int index = 0;
    return BzDB_BzArray_get(bzArray,index,res);
}

CCBOOL BzDB_BzArray_delete_last(BzDB_BzArray_t *bzArray  , void * res){
    int index = bzArray->used_count-1;
    return BzDB_BzArray_delete(bzArray,index,res);
}
CCBOOL BzDB_BzArray_delete_first(BzDB_BzArray_t *bzArray  , void * res){
    int index = 0;
    return BzDB_BzArray_delete(bzArray,index,res);
}



void BzDB_BzArray_demo(){

    typedef struct Person_t{
        char name[20];
        int age;
    }Person_t;


    BzDB_BzArray_t bzArray;
    Person_t person_list[20];

    BzDB_BzArray_init(&bzArray , person_list, sizeof(Person_t)  , 20);

    Person_t zhangsan;
    strcpy(zhangsan.name,"zhangsan");
    zhangsan.age = 20;

    BzDB_BzArray_insert(&bzArray,0,&zhangsan);

    Person_t lisi;
    strcpy(lisi.name,"lisi");
    lisi.age = 30;
    BzDB_BzArray_insert(&bzArray,1,&lisi);


    Person_t r_delete ;
    BzDB_BzArray_delete(&bzArray,0,&r_delete);
    printf("delete,%s,%d\n",r_delete.name,r_delete.age);

    Person_t res;
    BzDB_BzArray_get(&bzArray,0,&res);
    printf("%s,%d,%d\n",res.name,res.age,bzArray.used_count);

    strcpy(res.name,"wangwu");
    BzDB_BzArray_update(&bzArray,0,&res);

    Person_t res2;
    BzDB_BzArray_get(&bzArray,0,&res2);
    printf("after:%s,%d,%d\n",res2.name,res2.age,bzArray.used_count);
}